<?php
namespace Api\Controller;
use Think\Controller;
class PayController extends CommonController{

    //实例化用户
    protected $currentUser;
    
    function _initialize() {
        parent::_initialize();
        
        //判断token是否存在
        $token = I('post.token');

        $userMap['token'] = $token;
        $user = $this->userModel->where($userMap)->find();

        if(isNullOrEmpty($user)) {
            $this->errorReturn('ERROR_TOKEN');
        }

        $this->currentUser = $user;
        
    }

    //等待支付页
    public function payIndex() {

        //判断订单是否存在
        $orderId = I("post.orderId");

        $order = $this->orderModel->queryById($orderId);

        if(isNullOrEmpty($order)) {
            $this->errorReturn("ERROR_ORDER_NOT_FOUND");
        }

        if($order["user_id"] != $this->currentUser["user_id"]) {
            $this->errorReturn("ERROR_ORDER_NOT_FOUND");
        }

        if($order["status"] != C("ORDER_STATUS.WAITING_PAY")) {
            $this->errorReturn("ERROR_ORDER_STATUS_WRONG");
        }

        if(isNullOrEmpty($this->currentUser['openid'])) {
            $this->errorReturn('ERROR_NOT_FOUND_OPENID');
        }

        $pay = $this->payModel->queryById($order["pay_id"]);

        if (isNullOrEmpty($pay)) {

            $payId = $this->payModel->add(array(
                'out_trade_no' => time() . rand(0, 999),
                'order_id' => $orderId,
                'money' => $order['total_amount'],
                'status' => 0,
                'callback' => C('rooturl') . U('/Wechat/Api/WechatPay?orderId=' . $orderId),
                'create_time' => getCurrentDate(),
                'update_time' => getCurrentDate()
            ));

            $order['pay_id'] = $payId;

            $this->orderModel->updateObj($order);

            $pay = $this->payModel->queryById($payId);

        }
        //支付相关
        $arr = array(
            'appid' => C('appid'),
            'mch_id' => C('mch_id'),
            'nonce_str' => $this->createNoncestr(),
            //'sign' => '',	//签名
            'body' => '真心代喝订单',
            'out_trade_no' => $pay['out_trade_no'], //订单号
            'total_fee' => $order['total_amount'] * 100, //金额
            'spbill_create_ip' => get_client_ip(),
            'notify_url' => C('rooturl') . '/backend/index.php/wechat/api/wechatpay/', //通知地址
            'trade_type' => 'JSAPI',
            'openid' => $this->currentUser['openid'],
        );
        $arr['sign'] = $this->getSign($arr);  //签名

        $post = curl('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($arr));

        $arr2 = $this->xmlToArray($post);

        $jsApiObj["appId"] = C('appid');
        $timeStamp = time();
        $jsApiObj["timeStamp"] = "$timeStamp";
        $jsApiObj["nonceStr"] = $this->createNoncestr();
        $jsApiObj["package"] = "prepay_id=" . $arr2['prepay_id'];
        $jsApiObj["signType"] = "MD5";
        $jsApiObj["paySign"] = $this->getSign($jsApiObj);
        $parameters = json_encode($jsApiObj);

        $this->returnData['data']['config'] = $this->signature();
        $this->returnData['data']['webarr'] = $jsApiObj;

        $this->response($this->returnData, 'json');

    }
    /**
     * 	作用：生成签名
     */
    public function getSign($Obj) {

        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二：在string后加入KEY
        $String = $String . "&key=" . C('mch_key');
        //echo "【string2】".$String."</br>";
        //签名步骤三：MD5加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }

    /**
     * 	作用：array转xml
     */
    function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml.="<" . $key . ">" . $val . "</" . $key . ">";
            } else
                $xml.="<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
        $xml.="</xml>";
        return $xml;
    }

    function signature() {
        $Obj['jsapi_ticket'] = jsapi_ticket();
        $Obj['noncestr'] = createNoncestr();
        $Obj['url'] = "http://" . $_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI];
        $Obj['timestamp'] = time();

        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        //dump($Parameters);
        $String = formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二：在string后加入KEY
        //$String = $String."&key=".C('mch_key');
        //echo "【string2】".$String."</br>";
        //签名步骤三：MD5加密
        $String = sha1($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四：所有字符转为大写
        //$Obj['signature'] = strtoupper($String);
        $Obj['signature'] = $String;

        return $Obj;
    }

    /**
     * 	作用：产生随机字符串，不长于32位
     */
    public function createNoncestr($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str.= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 	作用：格式化参数，签名过程需要使用
     */
    function formatBizQueryParaMap($paraMap, $urlencode) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            //$buff .= strtolower($k) . "=" . $v . "&";
            $buff .= $k . "=" . $v . "&";
        }
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

    /**
     * 	作用：将xml转为array
     */
    public function xmlToArray($xml) {
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }


}